﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Tilver.Coder.Utility;
using Tilver.Coder.Win.Dialogs;
using Tilver.Coder.Core;
using Tilver.Coder;
using Tilver.Coder.Win.Views;
using Tilver.Common;
using System.Threading;

namespace Tilver.Coder.Win
{
    public partial class frmMain : Form
    {
        private LoaderBase _loader;//加载数据类
        private CoderProject _coderProject;//项目
        private string _projectDirectory;

        public frmMain()
        {
            InitializeComponent();

            InitProjectInfo();
            _loader = new DataLoader();
            _loader.LoadComplete += new LoadCompleteEventHandler(loader_LoadComplete);
            _loader.LoadDataBaseCompleted += new EventHandler<LoadDataBaseCompletedEventArgs>(loader_LoadDataBaseCompleted);
            _loader.LoadProgressChanged += new LoadProgressChangedEventHandler(loader_LoadProgressChanged);
            openFileDialog_Project_Open.Filter = string.Format("项目文件 (*{0})|*{0}", CommonUtil.ProjectFileExtension);
            openFileDialog_Project_Open.InitialDirectory = _projectDirectory;

            //loader.TickEvent += new EventHandler<TickEventArgs>(loader_TickEvent);
            //loader.LoadCompletedEvent += new Action<CoderProject>(loader_LoadCompletedEvent);
            //写日志
            //LoggerFactory.Create().Write("测试日志");
        }

        #region 初始化项目数据
        private void InitProjectInfo()
        {
            _projectDirectory = ConfigurationManager.AppSettings["ProjectDirectory"];
            if (!Directory.Exists(_projectDirectory))
            {
                Directory.CreateDirectory(_projectDirectory);
            }

        }
        #endregion

        #region 显示加载信息
        void loader_LoadProgressChanged(object sender, LoadProgressChangedEventArgs e)
        {
            txtMessage.AppendText(e.Message + Environment.NewLine);
        }
        #endregion

        #region 数据加载完成
        void loader_LoadComplete(object sender, LoadCompleteEventArgs args)
        {
            AddProjectToTreeView(args.Project);
        }
        #endregion

        #region TreeView操作

        #region 将数据加载到TreeView控件
        void loader_LoadDataBaseCompleted(object sender, LoadDataBaseCompletedEventArgs e)
        {
            if (tvProjectList.Nodes.Count == 0) { return; }
            var tnProject = tvProjectList.Nodes[0];
            tnProject.Nodes.Add(CreateTreeNode(e.DataBase));
        }
        private void AddProjectToTreeView(CoderProject project)
        {
            var tnProject = new TreeNode(string.Format("项目{0}({1}个数据库)", project.Name, project.DataBases.Count));
            tnProject.Tag = project;
            foreach (var dataBase in project.DataBases)
            {
                tnProject.Nodes.Add(CreateTreeNode(dataBase));
            }
            tvProjectList.Nodes.Add(tnProject);
        }
        private TreeNode CreateTreeNode(CoderDataBase cb)
        {
            var tnDataBase = new TreeNode(cb.CodeName, 0, 0);
            var tnTables = new TreeNode("表", 1, 1);
            var tnViews = new TreeNode("视图", 1, 1);
            var tnCommands = new TreeNode("存储过程", 1, 1);
            //显示表
            foreach (var tableInfo in cb.Tables)
            {
                var tnTable = new TreeNode(tableInfo.FullName, 2, 2);
                tnTable.Checked = tableInfo.IsBuild;
                tnTable.Tag = tableInfo;
                tnTables.Nodes.Add(tnTable);
            }
            //显示视图
            foreach (var viewInfo in cb.Views)
            {
                var tnView = new TreeNode(viewInfo.FullName, 3, 3);
                tnView.Checked = viewInfo.IsBuild;
                tnView.Tag = viewInfo;
                tnViews.Nodes.Add(tnView);
            }
            //显示存储过程
            foreach (var commandInfo in cb.Commands)
            {
                var tnCommand = new TreeNode(commandInfo.FullName, 4, 4);
                tnCommand.Checked = commandInfo.IsBuild;
                tnCommand.Tag = commandInfo;
                tnCommands.Nodes.Add(tnCommand);
            }
            tnDataBase.Tag = cb;
            tnDataBase.Nodes.Add(tnTables);
            tnDataBase.Nodes.Add(tnViews);
            tnDataBase.Nodes.Add(tnCommands);
            return tnDataBase;
            //tvProjectList.Invoke(new Action<TreeNode>(AddTreeNodeToTreeView), tnDataBase);
        }
        private void AddTreeNodeToTreeView(TreeNode node)
        {
            tvProjectList.Nodes.Add(node);
        }
        #endregion

        #region 选中树节点，是否生成代码
        private void tvProjectList_AfterCheck(object sender, TreeViewEventArgs e)
        {
            IBuildable buildable = e.Node.Tag as IBuildable;
            if (buildable != null)
            {
                buildable.IsBuild = e.Node.Checked;
            }
            foreach (TreeNode childNode in e.Node.Nodes)
            {
                childNode.Checked = e.Node.Checked;
            }
        }

        #endregion

        #region 双击树节点操作

        private void tvProjectList_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            var currentTreeNode = e.Node;
            if (currentTreeNode == null || currentTreeNode.Tag == null) return;
            if (currentTreeNode.Tag is CoderProject)
            {
                splitContainer_Main.Panel2.Controls.Clear();
                var projectView = new ProjectView();
                projectView.Dock = DockStyle.Fill;
                projectView.Project = currentTreeNode.Tag as CoderProject;
                splitContainer_Main.Panel2.Controls.Add(projectView);
            }
            else if (currentTreeNode.Tag is CoderDataBase)
            {
                splitContainer_Main.Panel2.Controls.Clear();
                var dataBaseView = new DataBaseView();
                dataBaseView.Dock = DockStyle.Fill;
                dataBaseView.DataBase = currentTreeNode.Tag as CoderDataBase;
                splitContainer_Main.Panel2.Controls.Add(dataBaseView);
            }
            else if (currentTreeNode.Tag is CoderTable || currentTreeNode.Tag is CoderView)
            {
                splitContainer_Main.Panel2.Controls.Clear();
                var tableView = new TableView();
                tableView.Dock = DockStyle.Fill;
                tableView.Tabular = currentTreeNode.Tag as CoderTabular;
                splitContainer_Main.Panel2.Controls.Add(tableView);
            }
            else if (currentTreeNode.Tag is CoderCommand)
            {
                splitContainer_Main.Panel2.Controls.Clear();
                var commandView = new CommandView();
                commandView.Dock = DockStyle.Fill;
                commandView.Command = currentTreeNode.Tag as CoderCommand;
                splitContainer_Main.Panel2.Controls.Add(commandView);
            }
            //else if (currentTreeNode.Tag is CGCommand)
            //{
            //    pnlRightContent.Controls.Clear();

            //    CommandView commandView = new CommandView();

            //    pnlRightContent.Controls.Add(commandView);
            //    commandView.Dock = DockStyle.Fill;
            //    commandView.SetCommandInfo(currentTreeNode.Tag as CGCommand);
            //}
            //else if (currentTreeNode.Tag is CGTabular)
            //{
            //    pnlRightContent.Controls.Clear();

            //    TableContentView tableContentView = new TableContentView();

            //    pnlRightContent.Controls.Add(tableContentView);
            //    tableContentView.Dock = DockStyle.Fill;
            //    tableContentView.SetTabularInfo(currentTreeNode.Tag as CGTabular);
            //}
        }

        #endregion

        #region 单击树节点操作
        private void tvProjectList_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                //Point clickPoint = new Point(e.X,e.Y);
                var currentNode = tvProjectList.GetNodeAt(e.Location);
                if (currentNode != null)
                {
                    tvProjectList.SelectedNode = currentNode;
                    if (currentNode.Tag is CoderDataBase)
                    {
                        //设置当前节点的快捷菜单
                        var cMenuStrip = cMenuStrip_TreeNode;
                        for (int i = 0; i < cMenuStrip.Items.Count; i++)
                        {
                            if (cMenuStrip.Items[i].Name == "tspMenu_ReLoadDataBase" || cMenuStrip.Items[i].Name == "tspMenu_DelDataBase")
                            {
                                cMenuStrip.Items[i].Enabled = true;
                            }
                            else
                            {
                                cMenuStrip.Items[i].Enabled = false;
                            }
                        }
                        currentNode.ContextMenuStrip = cMenuStrip_TreeNode;
                    }
                    if (currentNode.Tag is CoderProject)
                    {
                        var cMenuStrip = cMenuStrip_TreeNode;
                        for (var i = 0; i < cMenuStrip.Items.Count; i++)
                        {
                            if (cMenuStrip.Items[i].Name == "tspMenu_AddDataBase")
                            {
                                cMenuStrip.Items[i].Enabled = true;
                            }
                            else
                            {
                                cMenuStrip.Items[i].Enabled = false;
                            }
                        }
                        currentNode.ContextMenuStrip = cMenuStrip_TreeNode;
                    }
                }
            }
        }
        //重新加载数据库
        private void tspMenu_ReLoadDataBase_Click(object sender, EventArgs e)
        {
            var currentNode = tvProjectList.SelectedNode;
            if (currentNode != null && currentNode.Tag is CoderDataBase)
            {
                var currentDataBase = currentNode.Tag as CoderDataBase;
                //加载数据库
                foreach (var dataBase in _coderProject.DataBases)
                {
                    if (currentDataBase.Name == dataBase.Name)
                    {
                        dataBase.IsLoad = true;
                    }
                }
            }
            //CloseProject();
            LoadProject();

        }
        //添加数据库
        private void tspMenu_AddDataBase_Click(object sender, EventArgs e)
        {
            var currentNode = tvProjectList.SelectedNode;
            if (currentNode != null && currentNode.Tag is CoderProject)
            {
                var currentProject = currentNode.Tag as CoderProject;
                var cdb = new CreateDataBaseDialog();
                if (cdb.ShowDialog() == DialogResult.OK)
                {
                    _coderProject.DataBases.Add(cdb.DataBase);
                }
            }
            //CloseProject();
            LoadProject();
        }
        //删除数据库
        private void tspMenu_DelDataBase_Click(object sender, EventArgs e)
        {
            var currentNode = tvProjectList.SelectedNode;
            if (currentNode != null && currentNode.Tag is CoderDataBase)
            {
                var currentDataBase = currentNode.Tag as CoderDataBase;
                _coderProject.DataBases.Remove(_coderProject.DataBases.FirstOrDefault(c => c.Name == currentDataBase.Name));
            }
            //CloseProject();
            LoadProject();
        }
        #endregion
        #endregion

        #region 新建项目
        private void toolStripMenuItem_File_Create_Click(object sender, EventArgs e)
        {
            if (_coderProject == null)
            {
                CreateProject();
            }
            else
            {
                var showBox = MessageBox.Show("已存在打开项目，新建将关闭现有项目，建议先保存现有项目，确认要新建项目？", "新建项目确认框", MessageBoxButtons.YesNo);
                if (showBox == DialogResult.Yes)
                {
                    CreateProject();
                }
            }
        }

        /// <summary>
        /// 创建新项目
        /// </summary>
        private void CreateProject()
        {
            CloseProject();
            var cpd = new CreateProjectDialog();
            if (cpd.ShowDialog() == DialogResult.OK)
            {
                _coderProject = cpd.Project;
                LoadProject();
            }
        }
        /// <summary>
        /// 关闭现有项目
        /// </summary>
        private void CloseProject()
        {
            _coderProject = null;
            tvProjectList.Nodes.Clear();
            txtMessage.Clear();
        }
        /// <summary>
        /// 加载现有项目
        /// </summary>
        private void LoadProject()
        {
            tvProjectList.Nodes.Clear();
            _loader.Project = _coderProject;
            _loader.LoadSync();
        }
        #endregion

        #region 生成代码
        private void RenderToFile(CoderDataBase dataBase)
        {
            //生成表代码
            foreach (var table in dataBase.Tables.Where(w => w.IsBuild))
            {
                TabularToFile(table);
            }

            foreach (var view in dataBase.Views.Where(w => w.IsBuild))
            {
                TabularToFile(view);
            }

            foreach (var command in dataBase.Commands.Where(w => w.IsBuild))
            {
                TabularToFile(command);
            }
        }
        //生成代码
        private void TabularToFile(CoderTabular tabular)
        {
            var saveFilePath = string.Format("{0}\\{1}\\{2}.cs",
                   tabular.DataBase.Project.SaveDirectory,
                    tabular.DataBase.CodeName,
                    tabular.CodeName);
            var engineFactory = new Engine.EngineFactory();
            var engine = engineFactory.GetEngine(tabular);
            engine.RenderToFile(saveFilePath);
        }

        private void toolStripMenuItem_Operation_Create_Click(object sender, EventArgs e)
        {
            if (_coderProject != null)
            {
                foreach (var dataBase in _coderProject.DataBases)
                {
                    RenderToFile(dataBase);
                }
            }
        }
        #endregion

        #region 保存项目

        private void toolStripMenuItem_File_Save_Click(object sender, EventArgs e)
        {
            try
            {
                if (_coderProject == null) return;
                CommonUtil.SaveProject(_coderProject,
                Path.Combine(_projectDirectory, _coderProject.Name + CommonUtil.ProjectFileExtension));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion

        #region 打开项目

        private void toolStripMenuItem_File_Open_Click(object sender, EventArgs e)
        {
            CloseProject();
            if (openFileDialog_Project_Open.ShowDialog() == DialogResult.OK)
            {
                _coderProject = CommonUtil.LoadProject(openFileDialog_Project_Open.FileName);
                foreach (var dataBase in _coderProject.DataBases)
                {
                    dataBase.IsLoad = false;
                }
                LoadProject();
            }
        }
        #endregion

        #region 退出

        private void toolStripMenuItem_File_Exit_Click(object sender, EventArgs e)
        {
            this.Close();
        }
        #endregion

        #region 主窗口加载

        private void frmMain_Load(object sender, EventArgs e)
        {

        }

        #endregion

    }
}
